package alf.mapping.data;

import alf.common.data.AbstractDataService;
import alf.common.data.DataException;
import alf.mapping.dto.help.Category;
import alf.mapping.dto.help.Entry;
import alf.mapping.dto.help.Link;
import alf.mapping.view.Env;
import android.content.res.XmlResourceParser;
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.xmlpull.v1.XmlPullParser;
import org.xmlpull.v1.XmlPullParserException;
import org.xml.sax.Parser;

public class HelpLoader extends AbstractDataService {
	private static final String NAMESPACE = "http://www.w3.org/2005/Atom";

	public Map<String,Entry> parse(XmlResourceParser parser) throws DataException  {
		Map<String,Entry> map = null;
		try {
			parser.setFeature(XmlPullParser.FEATURE_PROCESS_NAMESPACES, true);
		//	Env.debug("parse.nextTag");
			parser.next();
			parser.nextTag();
			
			map = readMap(parser);
		} catch (XmlPullParserException e) {
			Env.error(e);
			encapsula("Xml error",e);
		} catch (IOException e) {
			Env.error(e);
			encapsula("File error",e);
		} finally {
			parser.close();
		}
		return map;
	}

	private Map<String,Entry> readMap(XmlPullParser parser) throws IOException, XmlPullParserException {
		Env.debug("readMap");
		Entry lastEntry;
		Map<String,Entry> map = new HashMap<String,Entry>();
		parser.require(XmlPullParser.START_TAG, NAMESPACE, "feed");
		while (parser.next() != XmlPullParser.END_TAG) {
			if (parser.getEventType() != XmlPullParser.START_TAG) {
				continue;
			}
			String tag = parser.getName();
			if (tag.equalsIgnoreCase("entry")) {
				lastEntry = readEntry(parser);
				map.put(lastEntry.getId(),lastEntry);
			} else {
				skip(parser);
			}
		}
		return map;
	}

	private Entry readEntry(XmlPullParser parser) throws IOException, XmlPullParserException {
		Env.debug("readEntry:"+debug(parser));
		Entry e = new Entry();
		parser.require(XmlPullParser.START_TAG, NAMESPACE, "entry");
		List<Link> links = new ArrayList<Link>();
		List<Category> cats = new ArrayList<Category>();

		while (parser.next() != XmlPullParser.END_TAG) {
			if (parser.getEventType() != XmlPullParser.START_TAG) {
				continue;
			}
			String tag = parser.getName();
		 	Env.debug("tag:"+tag);
			if (tag.equalsIgnoreCase("id")) {
				e.setId(readSimpleTag(parser,tag));
			} else if (tag.equalsIgnoreCase("title")) {
				e.setTitle(readSimpleTag(parser,tag));
			} else if (tag.equalsIgnoreCase("content")) {
				e.setContent(readSimpleTag(parser,tag));
			} else if (tag.equalsIgnoreCase("link")){
				Link k = readLink(parser);
				if (k.getRel()!=null && k.getRel().equals("icon")){
					e.setImage(k.getRef());
				} else {
					links.add(k);
				}
			} else if (tag.equalsIgnoreCase("category")){
				cats.add(new Category(readSimpleTag(parser,tag)));
			} else {
				skip(parser);
			}
		}
		e.setLinks(links.toArray(new Link[1]));
		e.setCategorys(cats.toArray(new Category[1]));
		return e;
	}

	private Link readLink(XmlPullParser parser) throws XmlPullParserException, IOException {
		Env.debug("readLink"+debug(parser));
		parser.require(XmlPullParser.START_TAG, NAMESPACE, "link");
		Link link = new Link();
		Env.debug("attrs " +parser.getAttributeCount());
		link.setRef(getAttr(parser, "href", "default"));
		link.setRel(getAttr(parser, "rel", null));
		Env.debug("href: "+link.getRef());
		Env.debug("rel:"+ link.getRel());
	
		while (parser.next() != XmlPullParser.END_TAG) {
			if (parser.getEventType() == XmlPullParser.TEXT) {
				link.setName(parser.getText());
			}
			if (parser.getEventType() != XmlPullParser.START_TAG) {
				continue;
			}
		//	skip(parser);
		}
		//parser.next();
		Env.debug("readlink.end:"+debug(parser));
		return link;
	}

	private String readSimpleTag(XmlPullParser ps, String tag) throws XmlPullParserException, IOException {
		String value = null;
		ps.require(XmlPullParser.START_TAG, NAMESPACE, tag);
		if (ps.next() == XmlPullParser.TEXT) {
			value = ps.getText();
			ps.nextTag();
		}
		return value;
	}
	
	private String debug(XmlPullParser p) throws XmlPullParserException  {
		String tag = p.getName();
		String msg = "?";
		switch(p.getEventType()){
			case XmlPullParser.START_TAG:
				msg = "<"+ tag + "...";
				break;
			case XmlPullParser.END_TAG:
				msg = "</" + tag + ">";
				break;
			case XmlPullParser.END_DOCUMENT:
				msg = "[End document]";
				break;
		}
		return msg;
	}
	
	private String getAttr(XmlPullParser parser, String name, String defaultVal) {
		String r = null;
		r = parser.getAttributeValue(null, name);
		if (r == null) {
			r = defaultVal;
		}
		return r;
	}

	private void skip(XmlPullParser parser) throws IllegalStateException, XmlPullParserException, IOException {
		if (parser.getEventType() != XmlPullParser.START_TAG) {
			throw new IllegalStateException();
		}
		int depth =1;
		while (depth != 0) {
			switch (parser.next()) {
				case XmlPullParser.END_TAG:
					depth--;
					break;
				case XmlPullParser.START_TAG:
					depth++;
					break;
			}
		}
	}
}
